package club.xyes.zkh.ecommerce.service.impl;

import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.exception.BadRequestException;
import club.xyes.zkh.ecommerce.commons.properties.WebsiteConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.properties.WechatConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.util.MultipartFileUtil;
import club.xyes.zkh.ecommerce.dao.mapper.ShopMapper;
import club.xyes.zkh.ecommerce.service.ShopService;
import club.xyes.zkh.ecommerce.wechat.dto.Code2SessionResult;
import club.xyes.zkh.ecommerce.wechat.service.WeChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * Create by 郭文梁 2019/4/16 0016 18:08
 * ShopServiceImpl
 * 商铺相关业务服务组件实现
 *
 * @author 郭文梁
 * @data 2019/4/16 0016
 */
@Service
@Slf4j
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements ShopService {
    private static final String DEFAULT_SHOP_LOGO = "default.png";
    private final ShopMapper mapper;
    private final WebsiteConfigurationProperties websiteConfigurationProperties;
    private final PasswordEncoder passwordEncoder;
    private final WechatConfigurationProperties wechatConfigurationProperties;
    private final WeChatService weChatService;

    @Autowired
    public ShopServiceImpl(ShopMapper mapper,
                           WebsiteConfigurationProperties websiteConfigurationProperties,
                           PasswordEncoder passwordEncoder,
                           WechatConfigurationProperties wechatConfigurationProperties,
                           WeChatService weChatService) {
        super(mapper);
        this.mapper = mapper;
        this.websiteConfigurationProperties = websiteConfigurationProperties;
        this.passwordEncoder = passwordEncoder;
        this.wechatConfigurationProperties = wechatConfigurationProperties;
        this.weChatService = weChatService;
    }

    @Override
    public Shop setLogo(Integer id, MultipartFile logoFile) throws IOException {
        Shop shop = getRequired(id);
        String path = websiteConfigurationProperties.getStaticFilePath() + websiteConfigurationProperties.getShopLogoPath();
        String filename = MultipartFileUtil.save(logoFile, path);
        shop.setLogoUrl(filename);
        return updateById(shop);
    }

    @Override
    public Shop create(Shop shop) {
        if (findByLoginName(shop.getLoginName()) != null) {
            throw new BadRequestException("登录名已存在");
        }
        String password = shop.getPassword();
        password = passwordEncoder.encode(password);
        shop.setLogoUrl(DEFAULT_SHOP_LOGO);
        shop.setPassword(password);
        return save(shop);
    }


    @Override
    public Shop setPromotionImage(Shop shop, MultipartFile promotionImageFile) throws IOException {
        String path = websiteConfigurationProperties.getStaticFilePath()
                + websiteConfigurationProperties.getShopPromotionImagePath();
        String filename = MultipartFileUtil.save(promotionImageFile, path);
        shop.setPromotionImage(filename);
        return updateById(shop);
    }

    @Override
    public Shop login(String loginName, String password, String code) {
        Shop shop = findByLoginName(loginName);
        if (shop == null) {
            throw new BadRequestException("登陆失败：用户不存在");
        }
        if (passwordEncoder.matches(password, shop.getPassword())) {
            shop = doWxLogin(shop, code);
            return shop;
        } else {
            throw new BadRequestException("登陆失败：密码错误");
        }
    }

    @Override
    public Shop resetPassword(Shop shop, String password) {
        String encodedPassword = passwordEncoder.encode(password);
        shop.setPassword(encodedPassword);
        return updateById(shop);
    }

    /**
     * 微信登录绑定
     *
     * @param shop shop对象
     * @param code 微信登录Code
     */
    private Shop doWxLogin(Shop shop, String code) {
        String appId = wechatConfigurationProperties.getShopMicroProgramAppId();
        String secret = wechatConfigurationProperties.getShopMicroProgramSecret();
        Code2SessionResult result = weChatService.code2Session(appId, secret, code);
        String openId = result.getOpenid();
        cleanOpenId(openId);
        if (Objects.equals(openId, shop.getWxOpenId())) {
            return shop;
        }
        shop.setWxOpenId(openId);
        return updateById(shop);
    }

    /**
     * 根据openID查找出商铺 并将其的OpenId设置为空
     *
     * @param openId openId
     */
    private void cleanOpenId(String openId) {
        int lines = mapper.cleanOpenId(openId);
        log.debug("Clean {} openId", lines);
    }

    /**
     * 通过登录名查找商铺
     *
     * @param loginName 登录名
     * @return 商铺
     */
    @Override
    public Shop findByLoginName(String loginName) {
        Shop query = new Shop();
        query.setLoginName(loginName);
        return findOneByQuery(query);
    }

    @Override
    public boolean existsByLoginName(String loginName, List<Integer> excludeIds) {
        Shop shop = findByLoginName(loginName);
        if (shop == null) {
            return false;
        }
        if (excludeIds == null || excludeIds.isEmpty()) {
            return true;
        }
        return !excludeIds.contains(shop.getId());
    }

    @Override
    public Shop loginByCode(String code) {
        String appId = wechatConfigurationProperties.getShopMicroProgramAppId();
        String secret = wechatConfigurationProperties.getShopMicroProgramSecret();
        Code2SessionResult result = weChatService.code2Session(appId, secret, code);
        String openId = result.getOpenid();
        return loginByOpenId(openId);
    }

    @Override
    public Shop loginByOpenId(String openId) {
        Shop query = new Shop();
        query.setWxOpenId(openId);
        Shop shop = mapper.selectOne(query);
        if (shop == null) {
            throw new BadRequestException("未登录：openId不匹配");
        }
        return shop;
    }

    @Override
    public Shop findBySn(String sn) {
        Shop query = new Shop();
        query.setSn(sn);
        return findOneByQuery(query);
    }
}
